import json
import time
from datetime import datetime

from django.core.exceptions import ObjectDoesNotExist
from django.db import transaction
from django.http import JsonResponse
from django.utils.dateparse import parse_datetime
from django.utils.timezone import is_aware, make_aware
from pytz import utc

from apps.accounts.models import CustomUser
from apps.accounts.views import is_captcha_valid
from apps.rootone.models import Class, CourseClassZj, Course, Other_teacher_class, ExaLocationZj, Location
from apps.studentapp.models import SStudents, S_award, student_award_zj
# 当出现一个模型定义在了两个models中的报错时，请注意views里面的导入模型类方式，应该是.models然后跟上模型类
from .models import Teacher, Teacher_user, teacher_award_zj, T_award, mb_setting, Leave_zong, set_Grades_course
from django.db.models import Q
from django.shortcuts import render
# Create your views here.
from django.http import JsonResponse
from rest_framework.decorators import api_view
#处理登录请求的导入
from rest_framework.response import Response
from rest_framework import status
import json

#导入API保护标签
from rest_framework.permissions import IsAuthenticated
from rest_framework.decorators import api_view, permission_classes


@api_view(['POST'])
# 已弃用
def teacherlogin(request):
    try:
        username_q = request.data.get('username')
        password_q = request.data.get('password')

        if not username_q and not password_q:
            return Response({'code': 2, 'message': '学号为空或密码为空！'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            teacher = Teacher.objects.get(sid=username_q)
        except Teacher.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到您的信息，请联系管理员'}, status=status.HTTP_404_NOT_FOUND)

        try:
            teacher_user = Teacher_user.objects.get(teacher_id=teacher)
            if teacher_user.password == password_q:
                return Response({'code': 1, 'message': '登录成功'}, status=status.HTTP_200_OK)
            else:
                return Response({'code': 2, 'message':'登录失败，密码校验错误'}, status=status.HTTP_401_UNAUTHORIZED)
        except Exception as e:
            return Response({'code': 2, 'message': f'未能找到您的用户信息'}, status=status.HTTP_404_NOT_FOUND)

    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def teacher_all_if(request):
    try:
        teacher_id_q = request.data.get('username')
        print(teacher_id_q)
        if not teacher_id_q:
            return Response({'code': 2, 'message': '教师编号不能为空'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            user = Teacher.objects.get(sid = teacher_id_q)

        except Teacher.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到您的信息，请联系管理员'}, status=status.HTTP_404_NOT_FOUND)
        try:
            user_allif = Teacher.objects.filter(sid=teacher_id_q).select_related('Teacher')
            all_if = user_allif.all().values()
            return JsonResponse({'code':1, 'data':list(all_if)}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({"code":2, 'message': f'无法查询您的个人信息，错误原因{str(e)}'}, status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([IsAuthenticated])
def head_if(request):
    try:
        # 获取请求参数
        teacher_id = request.query_params.get('username')  # 更改为从query_params获取

        if not teacher_id:
            return Response({'message': '教师编号异常！'}, status=status.HTTP_400_BAD_REQUEST)
        # 查询用户信息
        try:
            user_name = Teacher.objects.get(sid=teacher_id)
            really_name = user_name.rname
            # 修改一下逻辑，从班级模型里面来获取辅导员id然后判断
            # 遍历班级表，获取每个班级的fdy的工作编号，遍历成列表，然后判断登录的教师是否担任任何一个班的辅导员职位

            # 获取所有 Class 对象的 fdy 字段值
            fdy_objs = Class.objects.all().values('fdy')

            # 提取 fdy 对象中的 sid 字段
            fdy_sid = [
                i['fdy']
                for i in fdy_objs
            ]
            user_type = 'fdy' if str(teacher_id) in fdy_sid else 'teacher'
            # 返回数据结构更清晰
            return Response({
                'name': really_name,
                'user_type': user_type
            }, status=status.HTTP_200_OK)
        except ObjectDoesNotExist:
            return Response({'message': '教师编号不存在！'}, status=status.HTTP_404_NOT_FOUND)
    except Exception as e:
        # 捕获其他未知错误
        return Response({'message': f'服务器错误：{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# 查看奖状
@api_view(['POST'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def view_award(request):
    try:
        teacher_id = request.data.get('username')

        if not teacher_id:
            return Response({'message': '教师编号不能为空！'}, status=status.HTTP_400_BAD_REQUEST)

        teacher = Teacher.objects.filter(sid=teacher_id).first()

        if not teacher:
            return Response({'message': '未能找到此教师编号！'}, status=status.HTTP_404_NOT_FOUND)

        awards = teacher_award_zj.objects.filter(teacher_name=teacher)
        print(awards)
        if not awards.exists():
            return Response({'message': '该教师没有奖项数据！'}, status=status.HTTP_404_NOT_FOUND)
        awards_data = [
            {
                'award_id': award.teacher_award.award_id,
                'award_name': award.teacher_award.award_name,
                'award_unit': award.teacher_award.award_unit,
                'award_time': format(award.teacher_award.award_time,),
                'award_text': award.teacher_award.award_text,

            }
            for award in awards
        ]
        return JsonResponse({'code': 1, 'message': awards_data}, status=status.HTTP_200_OK)
    except Exception as e:
        return Response({'message': f'服务器错误：{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# 修改教师个人信息
@api_view(['POST'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def update_teacher_person(request):
    try:
        # 获取前端传来的数据
        teacher_id = request.data.get('teacherid')
        rname_q = request.data.get('username')
        sex_q = request.data.get('sex')
        birthday_q = request.data.get('birthday')
        phone_q = request.data.get('phone')
        email_q = request.data.get('email')
        orgin_q = request.data.get('orgin')
        level_q = request.data.get('level')

        # 查找教师信息
        try:
            user = Teacher.objects.get(sid=teacher_id)
        except Teacher.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到您的信息，请联系管理员'}, status=status.HTTP_404_NOT_FOUND)

        # 更新学生信息
        try:
            user.rname = rname_q
            user.sex = sex_q
            user.birthday = birthday_q
            user.phone = phone_q
            user.mailbox = email_q
            user.origin = orgin_q
            user.level = level_q
            user.save()

            return Response({'code': 1, 'message': '修改成功！'}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'code': 2, 'message': f'修改失败：{str(e)}'}, status=status.HTTP_400_BAD_REQUEST)

    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)



# 修改其他信息
@api_view(['POST'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def update_teacher_other(request):
    try:
        # 获取前端传来的数据
        teacher_id = request.data.get('teacherid')
        by_school_q = request.data.get('by_school')
        school_encode_q = request.data.get('school_encode')
        major_q = request.data.get('major')
        degree_q = request.data.get('degree')
        intro_q = request.data.get('intro')
        print(teacher_id)
        # 查找学生信息
        try:
            user = Teacher.objects.get(sid=teacher_id)
        except Teacher.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到您的信息，请联系管理员'}, status=status.HTTP_404_NOT_FOUND)

        # 更新学生信息
        try:
            user.by_school = by_school_q
            user.school_encode = school_encode_q
            user.major = major_q
            user.degree = degree_q
            user.intro = intro_q
            user.save()

            return Response({'code': 1, 'message': '修改成功！'}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'code': 2, 'message': f'修改失败：{str(e)}'}, status=status.HTTP_400_BAD_REQUEST)

    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误：{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)



# 修改工作信息
@api_view(['POST'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def update_teacher_work(request):
    try:
        # 获取前端传来的数据
        teacher_id = request.data.get('teacherid')
        posts_name_q = request.data.get('posts_name')
        posts_id_q = request.data.get('posts_id')
        org_q = request.data.get('org')
        hire_q = request.data.get('hire')
        # 查找教师信息
        try:
            user = Teacher.objects.get(sid=teacher_id)
        except Teacher.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到您的信息，请联系管理员'}, status=status.HTTP_404_NOT_FOUND)

        # 更新教师信息
        try:
            user.posts_name = posts_name_q
            user.posts_id = posts_id_q
            user.org = org_q
            user.hire = hire_q
            user.save()

            return Response({'code': 1, 'message': '修改成功！'}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'code': 2, 'message': f'修改失败：{str(e)}'}, status=status.HTTP_400_BAD_REQUEST)

    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误：{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# 修改家庭信息
@api_view(['POST'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def update_teacher_family(request):
    try:
        # 获取前端传来的数据
        teacher_id = request.data.get('teacherid')
        f_name_q = request.data.get('f_name')
        f_phone_q = request.data.get('f_phone')
        m_name_q = request.data.get('m_name')
        m_phone_q = request.data.get('m_phone')
        address_q = request.data.get('address')


        # 查找教师信息
        try:
            user = Teacher.objects.get(sid=teacher_id)
        except Teacher.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到您的信息，请联系管理员'}, status=status.HTTP_404_NOT_FOUND)

        # 更新教师信息
        try:
            user.f_name = f_name_q
            user.f_phone = f_phone_q
            user.m_name = m_name_q
            user.m_phone = m_phone_q
            user.address = address_q
            user.save()

            return Response({'code': 1, 'message': '修改成功！'}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'code': 2, 'message': f'修改失败：{str(e)}'}, status=status.HTTP_400_BAD_REQUEST)

    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误：{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)



# 修改密码
@api_view(['POST'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def update_teacher_password(request):
    try:
        # 获取前端传来的数据
        teacherid_q = request.data.get('teacherid')
        password_q = request.data.get('newPassword')

        # 查找教师信息
        try:
            user = Teacher_user.objects.get(teacher__sid=teacherid_q)
        except Teacher_user.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到您的信息，请联系管理员'}, status=status.HTTP_404_NOT_FOUND)

        # 更新个人密码
        try:
            user.password = password_q
            user.save()
            return Response({'code': 1, 'message': '修改成功！'}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'code': 2, 'message': f'修改失败：{str(e)}'}, status=status.HTTP_400_BAD_REQUEST)

    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误：{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)



@api_view(['POST'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def update_teacher_mb(request):
    """
    更新或创建教师的密保信息接口
    """
    try:
        # 获取请求中的数据
        teacherid = request.data.get('teacherid')
        mb_name1 = request.data.get('securityQuestion1')
        mb_answer1 = request.data.get('answer1')
        mb_name2 = request.data.get('securityQuestion2')
        mb_answer2 = request.data.get('answer2')
        mb_name3 = request.data.get('securityQuestion3')
        mb_answer3 = request.data.get('answer3')

        # 校验 teacherid 是否为空
        if not teacherid:
            return Response({'code': 2, 'message': '教师编号不能为空！'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            # 获取关联的教师实例
            teacher_instance = Teacher_user.objects.get(teacher__sid=teacherid)
        except Teacher_user.DoesNotExist:
            return Response({'code': 2, 'message': '教师信息不存在！'}, status=status.HTTP_404_NOT_FOUND)

        # 获取或创建密保信息
        user, created = mb_setting.objects.get_or_create(
            # !!!!在 Django 中，外键字段只能与相关的实例对象进行比较，而不能直接与实例对象的主键（ID）进行比较。
            teacher=teacher_instance,
            defaults={
                'teacher_id': teacher_instance.id,
                'mb_name1': mb_name1,
                'mb_answer1': mb_answer1,
                'mb_name2': mb_name2,
                'mb_answer2': mb_answer2,
                'mb_name3': mb_name3,
                'mb_answer3': mb_answer3,
            }
        )

        # 如果记录已存在，更新密保信息
        if not created:
            user.mb_name1 = mb_name1
            user.mb_answer1 = mb_answer1
            user.mb_name2 = mb_name2
            user.mb_answer2 = mb_answer2
            user.mb_name3 = mb_name3
            user.mb_answer3 = mb_answer3
            user.save()

        return Response({'code': 1, 'message': '密保信息更新成功！'}, status=status.HTTP_200_OK)

    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误：{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)




@api_view(['POST'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def load_teacher_mb(request):
    try:
        # 获取教师 ID
        teacher_id = request.data.get('teacherid')
        if not teacher_id:
            return Response({'code': 2, 'message': '需要查询密保信息的教师编号为空'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            user = Teacher.objects.get(sid=teacher_id)
        except Teacher.DoesNotExist:
            return Response({'code': 2, 'message': f'搜索不到教师编号 {teacher_id}'}, status=status.HTTP_404_NOT_FOUND)

        try:
            user_account = Teacher_user.objects.get(teacher=user)
        except Teacher_user.DoesNotExist:
            return Response({'code': 2, 'message': f'未找到学生账号信息 (student_id: {teacher_id})'}, status=status.HTTP_404_NOT_FOUND)

        # 查询 mb_setting 表获取密保信息
        try:
            mb_message = mb_setting.objects.filter(teacher=user_account).values(
                'mb_name1', 'mb_answer1',
                'mb_name2', 'mb_answer2',
                'mb_name3', 'mb_answer3'
            )
            if not mb_message.exists():
                return Response({'code': 2, 'message': '您还未设置密保信息，请尽快设置'},
                                status=status.HTTP_404_NOT_FOUND)

            # 返回查询结果
            return JsonResponse({'code': 1, 'data': list(mb_message)}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'code': 2, 'message': f'查询密保信息失败：{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误：{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)



# 忘记密码——密保校验
@api_view(['POST'])

def pwd_teacher_fg(request):
    try:
        teacher_id = request.data.get('username')
        captcha_key = request.data.get('captcha_key')
        captcha_value = request.data.get('captcha_value')

        if not captcha_key or not captcha_value:
            return Response({'message': '请输入验证码'}, status=status.HTTP_400_BAD_REQUEST)

            # 验证验证码
        if not is_captcha_valid(captcha_key, captcha_value):
            return Response({'message': '验证码错误'}, status=status.HTTP_400_BAD_REQUEST)

        if not teacher_id:
            return Response({'code': 2, 'message': '教师编号为空！'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            user = Teacher.objects.get(sid=teacher_id)
        except Teacher.DoesNotExist:
            return Response({'code': 2, 'message': f'搜索不到教师编号: {teacher_id}'}, status=status.HTTP_404_NOT_FOUND)

        try:
            user_mb = mb_setting.objects.filter(teacher=user).values(
                'mb_name1',
                'mb_name2',
                'mb_name3'
            )
            return JsonResponse({'code': 1, 'data': list(user_mb)}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'code': 2, 'message': f'查询密保信息失败：{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    except Exception as e:
        return Response({'code': 2, 'message':f'服务器错误：{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])

def verify_teacher_mb(request):
    try:
        teacher_id = request.data.get('username')
        security_answers = request.data.get('securityAnswers')  # 获取密保答案对象


        if not teacher_id:
            return Response({'code': 2, 'message': '教师编号为空！'}, status=status.HTTP_400_BAD_REQUEST)

        if not security_answers or len(security_answers) != 3:
            return Response({'code': 2, 'message': '密保答案不完整！'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            user = Teacher.objects.get(sid=teacher_id)
        except Teacher.DoesNotExist:
            return Response({'code': 2, 'message': f'搜索不到教师编号:  {teacher_id}'}, status=status.HTTP_404_NOT_FOUND)


        try:
            user_mb = mb_setting.objects.get(teacher=user)

            # 从数据库中获取用户的密保答案
            db_answer1 = user_mb.mb_answer1
            db_answer2 = user_mb.mb_answer2
            db_answer3 = user_mb.mb_answer3

            # 比较用户提供的答案与数据库中的密保答案
            if security_answers.get('question1') != db_answer1 or \
                    security_answers.get('question2') != db_answer2 or \
                    security_answers.get('question3') != db_answer3:
                return Response({'code': 2, 'message': '密保答案错误'}, status=status.HTTP_400_BAD_REQUEST)

            return Response({'code': 1, 'message': '校对密保答案成功, 请更新您的密码'}, status=status.HTTP_200_OK)

        except Exception as e:
            return Response({'code': 2, 'message': f'校对密保答案失败：{str(e)}'},
                            status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误：{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)



# 请假申请，学生发起请求
@api_view(['POST'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def student_leave_request(request):
    try:
        student_id_q = request.data.get('studentid')
        student_name_q = request.data.get('student_name')
        student_class_q = request.data.get('student_class')
        start_time_q = request.data.get('start_time')
        stop_time_q = request.data.get('stop_time')
        leave_cause_q = request.data.get('leave_cause')
        approver_q = request.data.get('approver')
        if not student_id_q:
            return Response({"code": 2, 'message': '学号为空！'}, status=status.HTTP_400_BAD_REQUEST)

        if not start_time_q or not stop_time_q or not leave_cause_q or not approver_q:
            return Response({"code": 2, 'message': '参数缺失！'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            # 实例化学生信息对象
            user = SStudents.objects.get(student_id=student_id_q)

        #     获取这名学生的班级id
            user_class_id = user.of_class.class_id

        #     从数据库中获取对应班级id的实例，也就是实例化对应班级id，用来抓取辅导员id
            class_object = Class.objects.get(class_id=user_class_id)

        #     拿取该班的辅导员id
            fdy_id = class_object.fdy_id

        #     实例化教师对象
            fdy_name = Teacher.objects.get(sid=fdy_id)

        except Exception as e:
            return Response({'code': 2, 'message': f'获取请假数据库之间的链路错误{str(e)}'}, status=status.HTTP_404_NOT_FOUND)
        if fdy_name.rname != approver_q:
            return Response({'code': 2, 'message': '审核人不匹配班级'}, status=status.HTTP_400_BAD_REQUEST)
        try:
            water = str(start_time_q.strip() +'_'+ student_id_q.strip())
            print(water)
            leave_data = Leave_zong(
                id=water,
                student_id=student_id_q,
                student_rname=student_name_q,
                student_class=student_class_q,
                start_time=start_time_q,
                stop_time=stop_time_q,
                leave_cause=leave_cause_q,
                approver_person=fdy_name,  # 传入 Teacher 对象
                approver_out=3,  # 审核状态默认为“审核中”
                approver_time=None  # 初始状态无审批时间
            )
            leave_data.save()
            return Response({'code': 1, 'message': '请假请求成功，等待审核吧~'}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'code':2, 'message': '创建请假请求失败'}, status=status.HTTP_400_BAD_REQUEST)

    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误：{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# 教师查看对应sid的申请记录

@api_view(['POST'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def teacher_view_leave(request):
    try:
        teacher_id = request.data.get('teacherid')
        if not teacher_id:
            return Response({'code': 2, 'message': '学号为空！'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            teacher_object = Teacher.objects.get(sid=teacher_id)
        except Teacher.DoesNotExist:
            return Response({"code": 2, "message": '找不到您的编号，请联系管理员'}, status=status.HTTP_404_NOT_FOUND)
        try:
    #             创建假条实例
            leave_objects = Leave_zong.objects.filter(approver_person=teacher_object, approver_out=3)
            teacher_approver = [
                {
                    'water': i.id,
                    'student_id': i.student_id,
                    'student_rname': i.student_rname,
                    'student_class': i.student_class,
                    'start_time': i.start_time.strftime('%Y-%m-%d %H:%M'),  # 格式化时间
                    'stop_time': i.stop_time.strftime('%Y-%m-%d %H:%M'),  # 格式化时间
                    'leave_cause': i.leave_cause,
                    'approver_person': i.approver_person.rname if i.approver_person else None,  # 返回审批人姓名
                    'approver_opinion': i.approver_opinion,
                    'approver_out': i.approver_out,
                    'approver_time': i.approver_time.strftime('%Y-%m-%d %H:%M') if i.approver_time else None,  # 格式化时间
                }
                for i in leave_objects
                ]
            return JsonResponse({"code": 1, "message": "获取成功", "data": teacher_approver}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'code': 2, 'message': f'错误原因：{str(e)}'}, status=status.HTTP_404_NOT_FOUND)

    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误：{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

# 审批假条，说白了就是改假条对应字段的参数
@api_view(['POST'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def approver_leave(request):
    try:
        water_id = request.data.get('water')
        approver_jg = request.data.get('approver_out')
        approver_opinion_q = request.data.get('approver_opinion')


        if not water_id:
            return Response({'code': 2, 'message': '假条单号为空！'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            # 实例化对应教师编号负责的教条流水
            leave_object = Leave_zong.objects.get(id=water_id)
            print(leave_object.approver_opinion)
            leave_object.approver_opinion = approver_opinion_q
            leave_object.approver_out = approver_jg
            leave_object.approver_time = datetime.now()
            leave_object.save()
            return Response({'code': 1, 'message': '审核成功'}, status=status.HTTP_200_OK)

        except Exception as e:
            return Response({'code': 2, 'message': f'错误原因：{str(e)}'}, status=status.HTTP_404_NOT_FOUND)



    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误：{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

# 查询通过或未通过的审批历史
@api_view(['POST'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def teacher_view_leave_his(request):
    try:
        teacher_id = request.data.get('teacherid')
        if not teacher_id:
            return Response({'code': 2, 'message': '学号为空！'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            teacher_object = Teacher.objects.get(sid=teacher_id)
        except Teacher.DoesNotExist:
            return Response({"code": 2, "message": '找不到您的编号，请联系管理员'}, status=status.HTTP_404_NOT_FOUND)
        try:
    #             创建假条实例
            leave_objects = Leave_zong.objects.filter(Q(approver_person=teacher_object) & (Q(approver_out=1) | Q(approver_out=2)))
            teacher_approver = [
                {
                    'water': i.id,
                    'student_id': i.student_id,
                    'student_rname': i.student_rname,
                    'student_class': i.student_class,
                    'start_time': i.start_time.strftime('%Y-%m-%d %H:%M'),  # 格式化时间
                    'stop_time': i.stop_time.strftime('%Y-%m-%d %H:%M'),  # 格式化时间
                    'leave_cause': i.leave_cause,
                    'approver_person': i.approver_person.rname if i.approver_person else None,  # 返回审批人姓名
                    'approver_opinion': i.approver_opinion,
                    'approver_out': i.approver_out,
                    'approver_time': i.approver_time.strftime('%Y-%m-%d %H:%M') if i.approver_time else None,  # 格式化时间
                }
                for i in leave_objects
                ]
            return JsonResponse({"code": 1, "message": "获取成功", "data": teacher_approver}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'code': 2, 'message': f'错误原因：{str(e)}'}, status=status.HTTP_404_NOT_FOUND)

    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误：{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)





# from django.utils import timezone
# # 教师获取班级信息
# @api_view(['POST'])
# def view_class(request):
#     try:
#         user_id = request.data.get('username')
#         print(f"Received rootid: {user_id}")
#         if not user_id:
#             return Response({'code': 2, 'message': '教师编号为空'}, status=status.HTTP_400_BAD_REQUEST)
#
#         try:
#             # 尝试获取管理员对象
#             teacher_object = Teacher.objects.get(sid=user_id)
#         except Teacher.DoesNotExist:
#             return Response({'code': 2, 'message': '不存在此编码对象'}, status=status.HTTP_404_NOT_FOUND)
#
#         try:
#             # 获取班级数据
#             class_datas = Class.objects.filter(root=root_object)
#
#             # 函数用于将 naive datetime 转换为带有时区信息的 ISO 8601 格式字符串
#             def format_datetime(dt):
#                 if dt and timezone.is_naive(dt):
#                     dt = timezone.make_aware(dt, timezone.utc)
#                 return dt.isoformat() if dt else None
#
#             class_data = [
#                 {
#                     'class_id': i.class_id,
#                     'class_name': i.class_name,
#                     'class_sum': i.class_sum,
#                     'class_type': i.class_type,
#                     'class_year': i.class_year,
#                     'notes': i.notes,
#                     'created_at': format_datetime(i.created_at),
#                     'updated_at': format_datetime(i.updated_at),
#                     'exe_person': i.root.really_name,
#                     'bzr': i.bzr.rname if i.bzr else '',  # 提取班主任的名字
#                     'fdy': i.fdy.rname if i.fdy else '',  # 提取辅导员的名字
#                     'root': i.root.root_id,
#                 }
#                 for i in class_datas
#             ]
#             print(class_datas[0].updated_at)
#
#             return Response({'code': 1, 'data': class_data}, status=status.HTTP_200_OK)
#         except Exception as f:
#             print(f"Error fetching class data: {f}")  # 输出查询班级时的错误
#             return Response({'code': 2, 'message': '查询班级信息失败！'}, status=status.HTTP_400_BAD_REQUEST)
#     except Exception as e:
#         print(f"Server error: {e}")  # 输出服务器错误信息
#         return Response({'code': 2, 'message': f'服务器错误{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
#


# 获取所有的学生奖项信息
@api_view(['GET'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def get_all_the_award(request):
    try:
        teacher_id = request.query_params.get('teacherid')

        if not teacher_id:
            return Response({'code': 2, 'message': '教师编号不能为空'})

        try:
            teacher_object = Teacher.objects.get(sid=teacher_id)
        except Teacher.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到该教师编号'}, status=status.HTTP_404_NOT_FOUND)

        try:
            award_date = S_award.objects.all().values(
                'award_id',
                'award_name'
            )

            return JsonResponse({'code': 1, 'data': list(award_date)}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'code': 2, 'message': f'获取全部奖项信息错误，错误原因：{str(e)}'}, status=status.HTTP_400_BAD_REQUEST)


    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# 教师（工作人员）为学生设置奖项
@api_view(['POST'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def teacher_create_student_award(request):
    try:
        teacher_id = request.data.get('teacherid')
        students = request.data.get('students')
        teachers = request.data.get('teachers')
        award_id_q = request.data.get('award_id')
        print(students)
        print(teachers)
        print(award_id_q)

        if not teacher_id:
            return Response({'code': 2, 'message': '教师编号不能为空'})

        try:
            teacher_object = Teacher.objects.get(sid=teacher_id)
        except Teacher.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到该教师编号'}, status=status.HTTP_404_NOT_FOUND)

    #     实例化奖项对象
        try:
            award_object = S_award.objects.get(award_id=award_id_q)
        except S_award.DoesNotExist:
            return Response({'code': 2, 'message': '不存在此奖项，请联系管理员'}, status=status.HTTP_404_NOT_FOUND)


    #     创建学生和奖项的中间表关系
        for student in students:
            try:
                # 先实例化传递进来的学号
                try:

                    student_object = SStudents.objects.get(student_id=student)

                except SStudents.DoesNotExist:
                    return Response({'code': 2, 'message': f'不存在学号{str(student)}'},
                                    status=status.HTTP_404_NOT_FOUND)
                object = student_award_zj.objects.create(student_name=student_object,
                                                student_award=award_object,
                                                )

                for teacher in teachers:
                    try:
                        teacher_object2 = Teacher.objects.get(sid=teacher)
                    except Teacher.DoesNotExist:
                        return Response({'code': 2, 'message': '未能找到该教师编号'}, status=status.HTTP_404_NOT_FOUND)
                    object.com_teacher_name=teacher_object2
                    object.save()
                return Response({'code': 1, 'message': f'学生:{str(student)}奖项分配成功'}, status=status.HTTP_200_OK)


            except Exception as e:
                return Response({'code': 2, 'message': '创建学生奖章中间信息失败'}, status=status.HTTP_400_BAD_REQUEST)

    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# 返回一个辅导员负责的班级
@api_view(['GET'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def teacher_view_my_class(request):
    try:
        teacher_id = request.query_params.get('teacherid')
        if not teacher_id:
            return Response({'code': 2, 'message': '教师编号不能为空'})

        try:
            teacher_object = Teacher.objects.get(sid=teacher_id)
        except Teacher.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到该教师编号'}, status=status.HTTP_404_NOT_FOUND)

        try:
    #         实例化班级对象合集
            class_objects_date = Other_teacher_class.objects.filter(teacher=teacher_object)
        except Other_teacher_class.DoesNotExist:
            return Response({'code': 2, 'message': f'实例化教师id{str(teacher_id)}关联的班级失败'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            class_date = [
                {'class_id': i.cclass.class_id,
                 'class_name': i.cclass.class_name
                }
                for i in class_objects_date
            ]
            return JsonResponse({'code': 1, 'data': list(class_date)})

        except Exception as e:
            return Response({'code': 2, 'message': '获取班级列表失败'}, status=status.HTTP_400_BAD_REQUEST)


    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)







# 教师查看一个班级应该考的科目信息
@api_view(['GET'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def get_all_the_course(request):

    try:
        teacher_id = request.query_params.get('teacherid')
        class_id_q = request.query_params.get('classid')

        if not teacher_id or not class_id_q:
            return Response({'code': 2, 'message': '教师编号或班级编号不能为空'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            teacher_object = Teacher.objects.get(sid=teacher_id)
        except Teacher.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到该教师编号'}, status=status.HTTP_404_NOT_FOUND)

        try:
            class_object = Class.objects.get(class_id=class_id_q)
        except Class.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到此班级'}, status=status.HTTP_404_NOT_FOUND)

        # 获取课程和班级中间表的实例化对象合集
        course_datas = CourseClassZj.objects.filter(cclass=class_object)

        # 提取课程ID并处理中间表关系
        for course_data in course_datas:
            course_object = course_data.course

            # 确保每个课程和班级的组合只被处理一次
            exa_location, created = ExaLocationZj.objects.get_or_create(
                course=course_object,
                cclass=class_object,
                defaults={
                    'location': None,
                    'start_at': None,
                    'end_at': None,
                    'teacher': None,
                }
            )

        # 实例化此班的考试课程安排合集
        ks_objects = ExaLocationZj.objects.filter(cclass=class_object)

        ks_objects_data = [
            {
                'course_id': i.course.course_id,
                'course_name': i.course.name,
                'start_time': i.start_at.isoformat() if i.start_at else None,
                'end_time': i.end_at.isoformat() if i.end_at else None,
                'location': i.location.location_id if i.location else '',
                'teacher': i.teacher.sid if i.teacher else ''
            }
            for i in ks_objects
        ]

        return Response({'code': 1, 'data': ks_objects_data}, status=status.HTTP_200_OK)

    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误: {str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)



# 为一门课程赋值考试地点，先获取指定时间段的实例，拿取地点id，确保唯一性，然后在获取指定班级的实例，对比时间是否唯一性

# 核心的时间比较方法
def times_equal_to_minute_precision(time1, time2):
    return (time1.hour == time2.hour and
            time1.minute == time2.minute)

@api_view(['POST'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def fdy_set_exa(request):
    try:
        teacher_id = request.data.get('teacherid')
        class_id_q = request.data.get('classid')
        course_id_q = request.data.get('courseId')
        start_time_q_str = request.data.get('startTime')  # 前端传递的时间字符串
        end_time_q_str = request.data.get('endTime')      # 前端传递的时间字符串
        location_q = request.data.get('location')
        invigilator_q = request.data.get('invigilator')



        if not teacher_id or not class_id_q:
            return Response({'code': 2, 'message': '教师编号或班级编号不能为空'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            teacher_object = Teacher.objects.get(sid=teacher_id)
        except Teacher.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到该教师编号'}, status=status.HTTP_404_NOT_FOUND)

        # 解析并标准化前端传递的时间
        start_time_q = parse_datetime(start_time_q_str)
        end_time_q = parse_datetime(end_time_q_str)



        # 确保前后端时间都是 aware 的，并且在 UTC 时区
        if not is_aware(start_time_q):
            start_time_q = make_aware(start_time_q, timezone=utc)
        if not is_aware(end_time_q):
            end_time_q = make_aware(end_time_q, timezone=utc)

        # 实例化指定时间的考试记录, 检查主监考人的同一时间编号唯一性
        exa_object = ExaLocationZj.objects.filter(
            Q(start_at=start_time_q) |
            Q(end_at=end_time_q)
        )

        for i in exa_object:

            if i.location.location_id == location_q or i.teacher.sid == invigilator_q:
                return Response({'code': 2, 'message': '时间段的关键值存在重复，请检查'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            class_object = Class.objects.get(class_id=class_id_q)
        except Class.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到此班级'}, status=status.HTTP_404_NOT_FOUND)

        # 检查班级是否有重复的时间段
        class_exa_objects = ExaLocationZj.objects.filter(cclass=class_object)

        for i in class_exa_objects:
            if i.teacher and i.teacher.sid == invigilator_q:
                return Response({'code': 2, 'message': '此时间段关键值存在重复，请检查'},
                                status=status.HTTP_400_BAD_REQUEST)

            if times_equal_to_minute_precision(i.start_at.astimezone(utc), start_time_q) or \
                    times_equal_to_minute_precision(i.end_at.astimezone(utc), end_time_q):
                return Response({'code': 2, 'message': '此时间段关键值存在重复，请检查'},
                                status=status.HTTP_400_BAD_REQUEST)

        # 开始进行修改操作
        try:

            now_km_object = Course.objects.get(course_id=course_id_q)
            loc_object = Location.objects.get(location_id=location_q)
            invigilator = Teacher.objects.get(sid=invigilator_q)


            # 尝试获取现有的考试记录进行更新，如果不存在则创建新的记录
            new_km_object, created = ExaLocationZj.objects.get_or_create(
                course=now_km_object,
                defaults={
                    'start_at': start_time_q.replace(second=0, microsecond=0),
                    'end_at': end_time_q.replace(second=0, microsecond=0),
                    'location': loc_object,
                    'teacher': invigilator,
                    'cclass': class_object
                }
            )
            if not created:
                new_km_object.start_at = start_time_q.replace(second=0, microsecond=0)
                new_km_object.end_at = end_time_q.replace(second=0, microsecond=0)
                new_km_object.location = loc_object
                new_km_object.teacher = invigilator
                new_km_object.save()

            return Response({'code': 1, 'message': '更新成功'}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'code': 2, 'message': f'更新错误: {e}'.format(str(e))}, status=status.HTTP_400_BAD_REQUEST)

    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误: {e}'.format(str(e))}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)



# 查询指定班级的绑定课程信息
@api_view(['GET'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def view_course_in_a_class(request):
    try:
        teacher_id = request.query_params.get('teacherid')
        class_id_q = request.query_params.get('classid')
        if not teacher_id or not class_id_q:
            return Response({'code': 2, 'message': '教师编号或班级编号不能为空'}, status=status.HTTP_400_BAD_REQUEST)

        try:
            teacher_object = Teacher.objects.get(sid=teacher_id)
        except Teacher.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到该教师编号'}, status=status.HTTP_404_NOT_FOUND)

        try:
            # get() 方法假定结果是唯一的。如果有超过一条记录满足条件，它将引发 MultipleObjectsReturned 异常；
            class_object = Class.objects.get(class_id=class_id_q)
        except Class.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到该班级编号'}, status=status.HTTP_404_NOT_FOUND)


    #     获取课程和班级表的中间对象合集
        try:
            course_class_zj_objects = CourseClassZj.objects.filter(cclass=class_object)
        except CourseClassZj.DoesNotExist:
            return Response({'code': 2, 'message': '此班级还为添加课程哦'} ,status=status.HTTP_404_NOT_FOUND)

        try:
            c_c_zj_data = [
                {
                    'course_id': i.course.course_id,
                    'course_name': i.course.name
                }
                for i in course_class_zj_objects
                ]
            print(c_c_zj_data)
            return JsonResponse({'code': 1, 'data': c_c_zj_data}, status=status.HTTP_200_OK)
        except Exception as e:
            return Response({'code': 2, 'message': '获取此班级的课程信息失败'}, status=status.HTTP_400_BAD_REQUEST)

    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误: {e}'.format(str(e))},
                        status=status.HTTP_500_INTERNAL_SERVER_ERROR)



# 辅导员获取初始化考试成绩
@api_view(['GET'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def fdy_set_gr(request):
    try:
        teacher_id = request.query_params.get('teacherid')
        class_id_q = request.query_params.get('classid')
        course_id_q = request.query_params.get('courseid')

        if not teacher_id or not class_id_q:
            return Response({'code': 2, 'message': '教师编号或班级编号不能为空'}, status=status.HTTP_400_BAD_REQUEST)

        # 验证教师、班级和课程的存在性
        try:
            teacher_object = Teacher.objects.get(sid=teacher_id)
        except Teacher.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到该教师编号'}, status=status.HTTP_404_NOT_FOUND)

        try:
            class_object = Class.objects.get(class_id=class_id_q)
        except Class.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到该班级编号'}, status=status.HTTP_404_NOT_FOUND)

        try:
            course_object = Course.objects.get(course_id=course_id_q)
        except Course.DoesNotExist:
            return Response({'code': 2, 'message': '未能找到此课程编号'}, status=status.HTTP_404_NOT_FOUND)

        # 返回指定班级、课程下的所有学生的成绩信息（即使成绩为空）
        student_objects = SStudents.objects.filter(of_class=class_object)
        students_data = [
            {
                "student_id": student.student_id,
                "name": student.rname,
                "usual_score": getattr(set_Grades_course.objects.filter(student=student, course=course_object).first(),
                                       'ps_gr', None),
                "exam_score": getattr(set_Grades_course.objects.filter(student=student, course=course_object).first(),
                                      'ks_gr', None),
                "total_score": getattr(set_Grades_course.objects.filter(student=student, course=course_object).first(),
                                       'z_gr', None)
            }
            for student in student_objects
        ]
        return Response({'code': 1, 'data': students_data}, status=status.HTTP_200_OK)

    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误: {str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)



# 为指定班级指定学生指定课程赋分
@api_view(['POST'])
@permission_classes([IsAuthenticated])  # 确保只有经过认证的用户可以访问
def update_students_scores(request):
    try:
        scores_data = request.data.get('data', [])

        if not isinstance(scores_data, list) or not scores_data:
            return Response({'code': 2, 'message': '没有提供有效的成绩数据'}, status=status.HTTP_400_BAD_REQUEST)

        with transaction.atomic():
            for score_data in scores_data:
                teacher_id = score_data.get('teacherid')
                class_id_q = score_data.get('classid')
                course_id_q = score_data.get('courseid')
                student_id = score_data.get('student_id')
                ps_gr_q = score_data.get('usual_score')
                ks_gr_q = score_data.get('exam_score')
                z_gr_q = score_data.get('total_score')

                if not ps_gr_q and not ks_gr_q and not z_gr_q:
                    return Response({'code': 2, 'message': '参数缺失！'}, status=status.HTTP_400_BAD_REQUEST)

                # 验证教师、班级和课程的存在性
                try:
                    teacher_object = Teacher.objects.get(sid=teacher_id)
                    class_object = Class.objects.get(class_id=class_id_q)
                    course_object = Course.objects.get(course_id=course_id_q)
                except (Teacher.DoesNotExist, Class.DoesNotExist, Course.DoesNotExist) as e:
                    return Response({'code': 2, 'message': f'未能找到指定的对象: {str(e)}'}, status=status.HTTP_404_NOT_FOUND)

                if not student_id:
                    continue  # 忽略无效的学生记录

                try:
                    student_obj = SStudents.objects.get(student_id=student_id)
                except SStudents.DoesNotExist:
                    continue  # 忽略不存在的学生记录

                # 判断操作的月份
                current_month = datetime.now().month
                if current_month in [1, 2, 3]:
                    qua = 2
                    year_student = datetime.now().year - 1
                elif current_month in [6, 7, 8, 9]:
                    qua = 1
                    year_student = datetime.now().year
                else:
                    return Response({'code': 2, 'message': '无效的季度请求'}, status=status.HTTP_400_BAD_REQUEST)

                try:
                    # 尝试获取已有的 set_Grades_course 实例
                    gr_obj = set_Grades_course.objects.get(student=student_obj, course=course_object)

                    # 更新成绩信息
                    gr_obj.ps_gr = ps_gr_q
                    gr_obj.ks_gr = ks_gr_q
                    gr_obj.z_gr = z_gr_q
                    gr_obj.year = str(year_student)
                    gr_obj.qua = qua
                    gr_obj.save()

                except set_Grades_course.DoesNotExist:
                    # 创建新的考试成绩信息实例
                    set_Grades_course.objects.create(
                        ps_gr=ps_gr_q,
                        ks_gr=ks_gr_q,
                        z_gr=z_gr_q,
                        student=student_obj,
                        course=course_object,
                        cclass=class_object,
                        qua=qua,
                        year=str(year_student),
                    )

        return Response({'code': 1, 'message': '成绩更新成功'}, status=status.HTTP_200_OK)

    except Exception as e:
        return Response({'code': 2, 'message': f'服务器错误: {str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)




